#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'wshu'
__version__ = '1.0'
"""
    ***********************************
    *  @filename : RBAC.py
    *  @Author : wshu
    *  @CodeDate : 2020/4/16 9:38
    *  @Software : PyCharm
    ***********************************
"""
from . import BaseModel
from sqlalchemy import Column
from sqlalchemy.sql import expression
from sqlalchemy import ForeignKey, Table, Index
from sqlalchemy.orm import relationship
from sqlalchemy import PrimaryKeyConstraint, UniqueConstraint, CheckConstraint
from sqlalchemy.types import (String, Integer, Boolean, Text, DateTime)

from core.comm.utils import timezone

# -_-
user_role = Table('user_roles', BaseModel.metadata,
                  Column('id', Integer, primary_key=True, autoincrement=True, nullable=True, comment='默认id'),
                  Column('user_id', Integer, ForeignKey('user.id'), nullable=False, comment='用户'),
                  Column('role_id', Integer, ForeignKey('role.id'), nullable=False, comment='角色'))
# -_-
class User(BaseModel):
    """
    用户模型
    """
    __tablename__ = 'user'

    username = Column(String(150), nullable=False, unique=True, comment='用户名')
    password = Column(String(128), nullable=False, comment='密码')
    realname = Column(String(150), nullable=True, comment='真实姓名')
    job_title = Column(String(50), nullable=True, comment='职位')
    is_superuser = Column(Boolean, server_default=expression.true(), nullable=False, comment='超级管理员')
    is_active = Column(Boolean, server_default=expression.true(), nullable=False, comment='活跃状态')
    date_joined = Column(DateTime(6), default=timezone.now, nullable=False, comment='加入时间')
    telphone = Column(String(30), nullable=True, comment='联系方式')
    email = Column(String(254), nullable=False, comment='邮箱地址')
    description = Column(Text, nullable=True, comment='用户描述')
    error_count = Column(Integer, nullable=False, default=0, comment='错误登录')
    lock_time = Column(DateTime, nullable=False, default=timezone.now, comment='锁定时间')
    # 角色关联
    roles = relationship('Role',
                         secondary=user_role,
                         backref='user_of_role')

    def __str__(self):
        return self.username

class Menu(BaseModel):
    """
    菜单设置
    """
    __tablename__ = "menu"

    title = Column(String(25), unique=True)
    icon = Column(String(50))
    # 父级菜单
    parent = Column(Integer, ForeignKey('menu.id'))
    # 正向/反向 - backref
    permission = relationship("Permission",
                              # primaryjoin="",
                              backref="menu")

    def __str__(self):
        return self.title

# -_-
role_permission = Table('role_permissions', BaseModel.metadata,
                    Column('id', Integer, primary_key=True, autoincrement=True, nullable=True, comment='默认id'),
                    Column('role_id', Integer, ForeignKey('role.id'), nullable=False, comment='角色'),
                    Column('permission_id', Integer, ForeignKey('permission.id'), nullable=False, comment='权限'))
# -_-
class Role(BaseModel):
    """
    角色：用于权限绑定
    """
    __tablename__ = "role"

    title = Column(String(25), unique=True)
    # 权限关联
    permission = relationship(
        'Permission',
        secondary=role_permission,
        backref='permission_of_role'
    )

    def __str__(self):
        return self.title

class Permission(BaseModel):
    """
    访问链接设置
    """
    __tablename__ = "permission"

    title = Column(String(50), unique=True)
    is_menu = Column(Boolean, server_default=expression.false(), nullable=False)
    url = Column(String(128))
    # 菜单关联
    menu_id = Column(Integer, ForeignKey('menu.id'))
    '''
    # 双向关联- 采用官方提倡的backref进行关联
    # menu = relationship('Menu',
    #                      back_populates="permission")
    '''
    def __str__(self):
        return '{menu}---{permission}'.format(menu=self.title, permission=self.title)
